#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>

#include <ctime>
#include <iostream>
#include <string>

#include "RingQueue.hpp"
#include "Task.hpp"

//--------- 传输任务版本 ---------------
using namespace std;

// 定义可能的运算符
string opers = "+-*/%";

// 生产者线程函数
void *Productor(void *args) {
  RingQueue<Task> *rq = static_cast<RingQueue<Task> *>(args);
  while (true) {
    int data1 = rand() % 10;
    usleep(10);
    int data2 = rand() % 10;
    usleep(10);
    char op = opers[rand() % opers.size()];

    Task task(data1, data2, op);
    rq->Push(task);
    printf("The thread-%3lu sent a task : %d %c %d = ?\n",
           pthread_self() % 1000, data1, op, data2);
    sleep(1);
  }
  return nullptr;
}

// 消费者线程函数
void *Consumer(void *args) {
  RingQueue<Task> *rq = static_cast<RingQueue<Task> *>(args);
  while (true) {
    Task task;
    rq->Pop(&task);
    task();
    printf("The thread-%3lu get a task : %d %c %d = %2d , exitcode: %d\n",
           pthread_self() % 1000, task.getnum1(), task.getoper(),
           task.getnum2(), task.getresult(), task.getexitcode());
    sleep(1);
  }
  return nullptr;
}

int main() {
  srand(time(nullptr));                         // 初始化随机数种子
  RingQueue<Task> *rq = new RingQueue<Task>();  // 创建任务队列

  pthread_t p_tids[1], c_tids[1];  // 定义1个生产者和1个消费者线程

  // 创建1个生产者线程
  pthread_create(&p_tids[0], nullptr, Productor, rq);

  // 创建1个消费者线程
  pthread_create(&c_tids[0], nullptr, Consumer, rq);

  // 等待生产者线程结束（实际上不会结束）
  pthread_join(p_tids[0], nullptr);

  // 等待消费者线程结束（实际上不会结束）
  pthread_join(c_tids[0], nullptr);

  delete rq;  // 释放队列内存（实际上不会执行到这里）
  return 0;
}

// ------- 纯内置类型版本 --------------

// using namespace std;

// // 生产者线程函数
// void *Productor(void *args) {
//   RingQueue<int> *rq = static_cast<RingQueue<int> *>(args);
//   while (true) {
//     int data = rand() % 10;  // 生成0-9的随机数
//     usleep(10);              // 短暂休眠，模拟生产过程
//     rq->Push(data);          // 将数据放入环形队列
//     printf("The thread-%3lu production a data :%2d\n", pthread_self() % 1000,
//            data);
//   }
//   return nullptr;
// }

// // 消费者线程函数
// void *Consumer(void *args) {
//   RingQueue<int> *rq = static_cast<RingQueue<int> *>(args);
//   while (true) {
//     int data = 0;
//     rq->Pop(&data);  // 从环形队列中取出数据
//     printf("The thread-%3lu get a data :%2d\n", pthread_self() % 1000, data);
//     usleep(800000);  // 休眠0.8秒，模拟消费过程
//   }
//   return nullptr;
// }

// int main() {
//   srand(time(nullptr));                       // 初始化随机数种子
//   RingQueue<int> *rq = new RingQueue<int>();  // 创建环形队列

//   pthread_t p_tids[3], c_tids[3];  // 定义3个生产者和3个消费者线程

//   // 创建3个生产者线程
//   for (size_t i = 0; i < 3; ++i) {
//     pthread_create(&p_tids[i], nullptr, Productor, rq);
//   }

//   // 创建3个消费者线程
//   for (size_t i = 0; i < 3; ++i) {
//     pthread_create(&c_tids[i], nullptr, Consumer, rq);
//   }

//   // 等待所有生产者线程结束
//   for (size_t i = 0; i < 3; ++i) {
//     pthread_join(p_tids[i], nullptr);
//   }

//   // 等待所有消费者线程结束
//   for (size_t i = 0; i < 3; ++i) {
//     pthread_join(c_tids[i], nullptr);
//   }

//   delete rq;  // 释放环形队列内存
//   return 0;
// }
